package com.example.pingze.service;

import com.example.pingze.entity.UserLogin;
import com.example.pingze.entity.UserLoginDetails;
import com.example.pingze.exception.PingZeException;
import com.example.pingze.repository.LoginRepository;
import com.example.pingze.utils.JwtUtil;
import com.example.pingze.utils.RedisCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestParam;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class LoginService {

    @Autowired
    private LoginRepository repository;
    @Autowired
    private PasswordEncoder encoder;
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private RedisCache redisCache;

//    String message = null;
    public String update(UserLogin userLogin) {
        boolean isValid = isValidPhoneNumber(userLogin.getAccount());
        if (isValid) {
            UserLogin findUserInfo = repository.findUserLoginByAccount(userLogin.getAccount());
            if(findUserInfo == null){
                throw new PingZeException("该账号未注册");
            }else {
                String password = userLogin.getPassword();
                String encode = encoder.encode(password);
                findUserInfo.setPassword(encode);
                repository.save(findUserInfo);
                return "修改成功";
            }
        } else {
            throw new PingZeException("该账号不合法，请重新输入");
        }
    }
    public String login(UserLogin userLogin) {
//        Map<String,String> map = new HashMap<>();
        String jwt = null;

        boolean isValid = isValidPhoneNumber(userLogin.getAccount());

        if (isValid) {
            UsernamePasswordAuthenticationToken authenticationToken =
                    new UsernamePasswordAuthenticationToken(userLogin.getAccount(),userLogin.getPassword());

            Authentication authenticate = authenticationManager.authenticate(authenticationToken);

            if (Objects.isNull(authenticate)) {
                throw new PingZeException("失败，请重新登录！");
            }

            UserLoginDetails userDetails = (UserLoginDetails) authenticate.getPrincipal();
            String userId = userDetails.getUserLogin().getId();
            jwt = JwtUtil.createJWT(userId);
//            map.put("token", jwt);
            redisCache.setCacheObject("userLogin:" + userId, userDetails);

//            UserLogin user = repository.findUserLoginByAccount(userLogin.getAccount());
//            if(user == null){
//                throw new PingZeException("用户不存在，请先注册!");
//            }
//            if(!user.getPassword().equals(userLogin.getPassword())){
//                throw new PingZeException("密码错误，请输入正确的密码！");
//            }else{
//                message = "登录成功";
//            }

        }else {
            throw new PingZeException("账号不合法，请重新输入");
        }
        return jwt;
    }
    public UserLogin register(UserLogin userLogin) {
        boolean isValid = isValidPhoneNumber(userLogin.getAccount());
        if(isValid == true){

            //用户密码加密存储到数据库中
            String encode = encoder.encode(userLogin.getPassword());
            userLogin.setPassword(encode);

            return repository.save(userLogin);
        }else {
            throw new PingZeException("账号不合法，请重新输入");
        }
    }

    public static boolean isValidPhoneNumber(String phoneNumber) {
        // 根据中国大陆手机号的格式，使用正则表达式进行验证
        String regex = "1[3456789]\\d{9}";

        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(phoneNumber);

        return matcher.matches();
    }

    public UserLogin findUserLoginByAccount(String account) {
        return repository.findUserLoginByAccount(account);
    }

    public void delete(UserLogin find) {

        UsernamePasswordAuthenticationToken authentication =
                (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        UserLoginDetails userLoginDetails = (UserLoginDetails) authentication.getPrincipal();
        String userId = userLoginDetails.getUserLogin().getId();
        redisCache.deleteObject("userLogin:" + userId);

        repository.delete(find);
    }

    public Page getUserLoginList(UserLogin userLogin, Pageable pageable) {
        Specification specification = new Specification() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if(!StringUtils.isEmpty(userLogin.getAccount())){
                    predicates.add(criteriaBuilder.equal(root.get("account"), "%" + userLogin.getAccount() + "%"));
                }
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };

        Page page = repository.findAll(specification, pageable);
        return page;
    }

    public UserLogin add(UserLogin userLogin) {
        if(userLogin != null){
            userLogin.setId(UUID.randomUUID().toString());
        }
        UserLogin save = repository.save(userLogin);
        return save;
    }

    public UserLogin edit(String account, String password) {
        UserLogin loginById = repository.findUserLoginByAccount(account);
        if(!loginById.getPassword().equals(password)){
            loginById.setPassword(password);
        }
        return repository.save(loginById);
    }

    public void deleteUserLoginByAccount(String account) {
        UserLogin find = repository.findUserLoginByAccount(account);
        if(find != null){
            repository.delete(find);
        }else{
            throw new PingZeException("该account为空");
        }
    }
}
